package clients;

import shared.*;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

import javax.swing.JOptionPane;

public class Client 
{
	public static final String rmiObjectName  = "StockServer";
	public static String remoteHostName = "";
	public static String userName       = "";
	public static boolean exit          = false;

	private User currentUser;
	private ServerRemoteInterface remoteServer;

	public static void main(String[] args) 
	{

		
		Client client;
		while (true)
		{
			LogOnWindow logOnWindow = new LogOnWindow();
			logOnWindow.setModal(true);
			logOnWindow.setVisible(true);
			
			if (exit == true)
			{
				logOnWindow.dispose();
				return;
			}
			
			if (Client.userName.length() == 0)
			{
				JOptionPane.showMessageDialog(null, "Username cannot be empty, please try again!");
				continue;
			}
			
			
			javax.swing.JLabel label = new javax.swing.JLabel();
			label.setText("Logging on, please wait..");
			label.setFont(new java.awt.Font("Jokerman", java.awt.Font.PLAIN, 35));
			label.setSize(300, 300);
			javax.swing.Popup popUp = javax.swing.PopupFactory.getSharedInstance().getPopup(null, label, 300, 300);
			popUp.show();
					
			client = new Client();
			popUp.hide();
			
			if (client.remoteServer != null && client != null)
			{
				JOptionPane.showMessageDialog(null, "Log on succeed!");
				logOnWindow.dispose();
				break;
			}
			else
				JOptionPane.showMessageDialog(null, "Log on failed (remote host can't be reached), please try again!");
		}
		
		String tempUsername = client.userName;
		tempUsername = tempUsername.toLowerCase();
		System.out.println(tempUsername);
		
		if (!tempUsername.equals("superuser"))
		{
			ClientFrame frame = new ClientFrame(client);
			frame.setVisible(true);
		}
		else
		{
			SuperUserFrame superFrame = new SuperUserFrame(client);
			superFrame.setVisible(true);
		}
		

	}

	
	
	public Client() 
	{
		
		// initialize RMI connection
		if (System.getSecurityManager() == null) 
		{
			//System.setSecurityManager(new SecurityManager());
		}
		try 
		{
			Registry registry = LocateRegistry.getRegistry(remoteHostName);
			this.remoteServer = (ServerRemoteInterface) registry.lookup(rmiObjectName);
			if (this.remoteServer != null)
				this.currentUser  = this.remoteServer.getUser(userName);
		} 
		catch (Exception e) 
		{
			System.err.println("Failed to get reference to remote stock server!");
			return;			
		}
		
		//test
		try 
		{
			if (this.remoteServer != null)
				System.out.println(this.remoteServer.test());
		} 
		catch (RemoteException e) 
		{
			e.printStackTrace();
		}
		//test ends
	}
	
	
	public ArrayList<Stock> getAllStocks()
	{
		List<Stock> list = new ArrayList<Stock>(); 
		try 
		{
			list = this.remoteServer.getAllStocks();
		} 
		catch (RemoteException e) 
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return (ArrayList<Stock>) list;
	}

	public void commandLine(){
		Scanner input = new Scanner(System.in);
		String line;
//		System.out.println("Please Enter the remote stock server name: ");
//		Client.remoteHostName = line;
		System.out.println("Please Enter your user name, if you don't have one, the name you entered will be your user name: ");
		line = input.nextLine();
		Client.userName = line;
		int s = logon(Client.userName);
		while (s !=0){		
			System.out.println("Logon failed, re-login");
			s = logon(Client.userName);
			}
		System.out.println("\n\n");
		System.out.println("******************Welcome "+this.currentUser.getName()+"*****************");

		while (true){
			System.out.println("Press enter key to continue");
			line = input.nextLine();
			System.out.println("What do you want to do today?");
			System.out.println("1.Query a Stock");
			System.out.println("2.Buy Stock");
			System.out.println("3.Sell Stock");
			System.out.println("4.View my account info");
			System.out.println("5.Exit");
			int choice;
			line = input.nextLine();
			try{
				choice = Integer.parseInt(line);
			}catch (Exception e){
				System.out.println("Invalid selction !");
				continue;
			}
			int amount;
			Status status;
			String stockName;
			switch (choice){
			case 1:
				System.out.println("You selected 1.Query a Stock");
				System.out.println("Please enter the stock ticker name");
				line = input.nextLine();
				Stock stock= this.queryStock(line);
				if (stock == null){
					System.out.println("Sorry, The ticker symbol you entered is not found !");
				}
				else {
					System.out.println(stock);
				}
				break;
			case 2:
				System.out.println("You selected 2.Buy Stock");
				System.out.println("Please enter the ticker name you wish to buy");
				stockName = input.nextLine();
				System.out.println("Please enter the amount");
				line = input.nextLine();
				try{
					amount = Integer.parseInt(line);
				}catch (Exception e){
					System.out.println("Invalid amount !");
					break;
				}
				status = this.buy(stockName, amount);
				System.out.println(status.getMessage());
				break;
			case 3:
				System.out.println("You selected 3.Sell Stock");
				System.out.println("Please enter the ticker name you wish to sell");
				stockName = input.nextLine();
				System.out.println("Please enter the amount");
				line = input.nextLine();
				try{
					amount = Integer.parseInt(line);
				}catch (Exception e){
					System.out.println("Invalid amount !");
					break;
				}
				status = this.sell(stockName, amount);
				System.out.println(status.getMessage());
				break;
			case 4:
				System.out.println("You selected 4.View my Info");
				System.out.println(this.currentUser);
				break;
			case 5:
				System.out.println("Bye bye!");
				return;
			default:
				break;
			}
			
		}
		
		
		
	}
	
	public int logon(String userName) 
	{	
		try
		{
			this.currentUser = this.remoteServer.getUser(userName);
		} 
		catch (RemoteException e) 
		{
			
			System.err.println("Fail to logon: ");
			e.printStackTrace();
			return 1;
		}
		
		return 0;
	}

	
	
	public Stock queryStock(String stockName) 
	{
		Stock stock = null;
		
		try 
		{
			stock = this.remoteServer.queryStock(stockName);
		} 
		catch (RemoteException e) 
		{
			e.printStackTrace();
		}
		
		return stock;
	}

	
	
	public Status buy(String stockName, int numberOfStocks) 
	{
		Status status = new Status();
		
		try 
		{
			
			status = this.remoteServer.buy(stockName, numberOfStocks, this.currentUser.getName());
			this.currentUser = this.remoteServer.getUser(this.currentUser.getName());
			
		} 
		catch (RemoteException e) 
		{
			System.err.println("Failed to buy");
			status.setCode(122);
			status.setMessage("Failed to buy");
			e.printStackTrace();
		}
		
		return status;
	}

	
	
	public Status sell(String stockName, int numberOfStocks) 
	{
		Status status = new Status();
		int number = 0;
		try 
		{
			status = this.remoteServer.sell(stockName, numberOfStocks, this.currentUser.getName());
			this.currentUser = this.remoteServer.getUser(this.currentUser.getName());
		} 
		catch (RemoteException e) 
		{
			// TODO Auto-generated catch block
			System.err.println("Failed to buy");
			e.printStackTrace();
		}
		return status;
	}
	
	
	public Status modify(String stockName, double newPrice)
	{
		Status status = new Status();
		
		try 
		{
			status = this.remoteServer.modifyStockPrice(stockName, newPrice);
		} 
		catch (RemoteException e) 
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return status;
	}



	public User getCurrentUser() {
		return currentUser;
	}



	public void setCurrentUser(User currentUser) {
		this.currentUser = currentUser;
	}

	
	
}
